package org.jeecg.modules.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.repository.Model;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.dto.ActProcessDef;
import org.jeecg.modules.dto.OutProcessDefElementDto;
import org.jeecg.modules.entity.ActProcdefBusinessEntity;
import org.jeecg.modules.service.IActProcessDefService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.io.*;
import java.util.List;

/**
 * @Description: 流程部署
 * @Author: jeecg-boot
 * @Date: 2023-12-06
 * @Version: V1.0
 */
@Api(tags = "流程部署")
@RestController
@RequestMapping("/act/procdef")
@Slf4j
public class ActProcessDefController extends JeecgController {
    @Autowired
    private IActProcessDefService service;

    /**
     * 分页列表查询
     *
     * @param actProcessDef
     * @param req
     * @return
     */
    // @AutoLog(value = "流程部署-分页列表查询")
    @ApiOperation(value = "流程部署-分页列表查询", notes = "流程部署-分页列表查询")
    @GetMapping(value = "/listPage")
    public Result<IPage<ActProcessDef>> listPage(ActProcessDef actProcessDef,
            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
            HttpServletRequest req) {
        IPage<ActProcessDef> list = service.listPage(actProcessDef, pageNo, pageSize);
        return Result.OK(list);
    }

    @ApiOperation(value = "流程部署-列表查询", notes = "流程部署-列表查询")
    @GetMapping(value = "/list")
    public Result<List<ActProcessDef>> list(ActProcessDef actProcessDef,
            HttpServletRequest req) {
        List<ActProcessDef> list = service.list(actProcessDef);
        return Result.OK(list);
    }

    @ApiOperation(value = "流程部署-历史列表查询", notes = "流程部署-历史列表查询")
    @GetMapping(value = "/listHistory")
    public Result<List<ActProcessDef>> listHistory(@RequestParam String procDefKey, HttpServletRequest req) {
        List<ActProcessDef> list = service.listHistory(procDefKey);
        return Result.OK(list);
    }

    @ApiOperation(value = "查询节点集合", notes = "查询流程定义的节点集合")
    @GetMapping(value = "/listFlowElement")
    public Result<List<OutProcessDefElementDto>> listFlowElement(String processDefId, HttpServletRequest req) {
        List<OutProcessDefElementDto> list = service.listFlowElement(processDefId);
        return Result.OK(list);
    }

    @RequiresPermissions("act:procdef:updateState")
    @GetMapping(path = "/updateState")
    @ApiOperation(value = "设置流程状态", notes = "根据procDefId设置流程状态")
    public Result<String> updateState(@RequestParam("procDefId") String procDefId,
            @RequestParam("state") String state) {
        String msg = service.updateState(procDefId, state);
        return Result.OK(msg);
    }

    @GetMapping(path = "/resourceImage")
    @ApiOperation(value = "获取流程图", notes = "根据procDefId获取流程xml")
    public void resourceImage(@RequestParam("procDefId") String procDefId, HttpServletResponse response)
            throws Exception {
        final InputStream inputStream = service.getFlowchart(procDefId);
        StreamUtils.copy(inputStream, response.getOutputStream());
    }

    @GetMapping(path = "/getProcdefBusiness")
    @ApiOperation(value = "获取业务数据", notes = "获取流程定义的关联业务数据")
    public Result<ActProcdefBusinessEntity> getProcdefBusiness(@RequestParam @Valid String procdefId,
            HttpServletResponse response) throws Exception {
        ActProcdefBusinessEntity entity = service.findByProcdefId(procdefId);
        log.info(procdefId, entity);
        return Result.OK("获取业务数据成功！", entity);
    }

    @PostMapping(path = "/addProcdefBusiness")
    @ApiOperation(value = "新增业务数据", notes = "新增流程定义的关联业务数据")
    public Result<Integer> addProcdefBusiness(@RequestBody @Valid ActProcdefBusinessEntity businessEntity,
            HttpServletResponse response) throws Exception {
        int i = service.saveProcdefBusiness(businessEntity);
        return Result.OK("新增业务数据成功！", i);
    }

    @PostMapping(path = "/updateProcdefBusiness")
    @ApiOperation(value = "更新业务数据", notes = "更新流程定义的关联业务数据")
    public Result<Integer> updateProcdefBusiness(@RequestBody @Valid ActProcdefBusinessEntity businessEntity,
            HttpServletResponse response) throws Exception {
        int i = service.updateProcdefBusiness(businessEntity);
        return Result.OK("更新业务数据成功！", i);
    }

    // @RequiresPermissions("act:procdef:resourceRead")
    @GetMapping(path = "/resourceXml")
    @ApiOperation(value = "获取流程xml", notes = "根据procDefId获取流程xml")
    public void resourceXml(@RequestParam("procDefId") String procDefId, HttpServletResponse response)
            throws Exception {
        InputStream inputStream = service.resourceRead(procDefId, null, "xml");
        StreamUtils.copy(inputStream, response.getOutputStream());
    }

    @RequiresPermissions("act:procdef:convertToModel")
    @GetMapping(path = "/convertToModel")
    @ApiOperation(value = "转换为模型", notes = "根据procDefId转换为模型")
    public Result<Model> convertToModel(@RequestParam("procDefId") String procDefId) {
        Model model = null;
        try {
            model = service.convertToModel(procDefId);
        } catch (Exception e) {
            return Result.error("转换为模型失败!");
        }
        return Result.OK("成功转换为模型！", model);
    }

    /**
     * 添加
     *
     * @param file
     * @param category
     * @param request
     * @return
     */
    @AutoLog(value = "流程部署-添加")
    @ApiOperation(value = "流程部署-添加", notes = "流程部署-添加")
    @RequiresPermissions("act:procdef:add")
    @PostMapping(value = "/add")
    public Result<String> add(@RequestParam(value = "file") MultipartFile file, @RequestParam String category,
            HttpServletRequest request) {
        String fileName = file.getOriginalFilename();

        if (StringUtils.isBlank(fileName)) {
            return Result.error("请选择要部署的流程文件");
        }

        String message = service.deploy(category, file);

        return Result.OK(message);
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "流程部署-通过id删除")
    @ApiOperation(value = "流程部署-通过id删除", notes = "流程部署-通过id删除")
    @RequiresPermissions("act:procdef:delete")
    @DeleteMapping(value = "/delete")
    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
        service.deleteByDeployId(id);
        return Result.OK("删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    // @AutoLog(value = "流程部署-通过id查询")
    @ApiOperation(value = "流程部署-通过id查询", notes = "流程部署-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<ActProcessDef> queryById(@RequestParam(name = "id", required = true) String id) {

        return Result.OK();
    }

}
